package com.xuchen.zhenyang.core.aop;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.xuchen.zhenyang.core.annotation.CheckNullUpdate;
import com.xuchen.zhenyang.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class AopCore {

    @Pointcut("@annotation(com.xuchen.zhenyang.core.annotation.RequestLog)")
    void requestLog() {
    }

    @Pointcut("@annotation(com.xuchen.zhenyang.core.annotation.CheckNullUpdate) ")
    void checkNullUpdate() {
    }

    @Before("requestLog()")
    void requestLog(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        if ("get".equalsIgnoreCase(request.getMethod())) {
            log.info("Get请求[{}]入参:[{}]", request.getRequestURI(), getJsonParams(request.getParameterMap()));
        } else {
            log.info("Post请求[{}]入参:[{}]", request.getRequestURI(), JSONUtil.toJsonStr(joinPoint.getArgs()[0]));
        }
    }

    @Before(value = "checkNullUpdate()")
    void CheckNullUpdate(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String updateField = request.getParameter("updateField");
        Object myEntity = joinPoint.getArgs()[0];
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        CheckNullUpdate check = method.getAnnotation(CheckNullUpdate.class);
        if (check != null) {
            String[] checkFields = check.value();
            for (String checkField : checkFields) {
                if (checkField.equals(updateField)) {
                    Object value = ReflectUtil.getFieldValue(myEntity, updateField);
                    if (value == null || StrUtil.isBlank(String.valueOf(value))) {
                        throw new BusinessException("该值不能为空");
                    }
                    return;
                }
            }
        }
    }

    private static String getJsonParams(Map<String, String[]> map) {
        Map<String, String> paramsMap = new HashMap<>();
        for (Map.Entry<String, String[]> entry : map.entrySet()) {
            paramsMap.put(entry.getKey(), entry.getValue()[0]);
        }
        return JSONUtil.toJsonStr(paramsMap);
    }
}
